package korkd.tower;

import java.util.LinkedList;

import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.engine.camera.hud.HUD;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.handler.timer.ITimerCallback;
import org.anddev.andengine.engine.handler.timer.TimerHandler;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.font.Font;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.util.path.Path;
import android.graphics.Color;
import android.graphics.Typeface;
import android.view.MotionEvent;
import android.widget.Toast;

public class TowerDefenseGame implements IOnSceneTouchListener {
	
	private Castle mCastle;
	private Scene mScene;
	private Map mTowerMap;
	private Path mPath;
	private BitmapTextureAtlas mFontTexture;
	private Font mFont;
	private BitmapTextureAtlas mTexture;
	private TextureRegion mTowerTextureRegion;
	private TiledTextureRegion mPlayerTextureRegion;
	private TextureRegion mBulletTextureRegion;
	private TextureRegion mTowerRangeTextureRegion;
	private UnitPool mUnitPool;
	private BulletPool mBulletPool;
	private LinkedList<Tower> mTowers = new LinkedList<Tower>();
	private boolean mPlaceTower;
	private LinkedList<TMXTile> mUsedTiles = new LinkedList<TMXTile>();
	private Player mPlayer;
	private int mUnitSpawned;
	private IUpdateHandler mGlideHandler;
	private float mTouchX;
	private float mTouchY;
	private float mTouchOffsetX;
	private float mTouchOffsetY;
	private Scene oldScene;
	
	TowerDefenseGame(Castle pCastle, Player pPlayer, Path pPath)
	{
		mCastle = pCastle;
		mPlayer = pPlayer;
		mUnitSpawned = 25;
		mPath = pPath;
		
		mScene = new Scene();
		
		mScene.setOnSceneTouchListener(this);
				
		mUnitPool = new UnitPool(mPlayerTextureRegion, mScene, mTowerMap.getMap(), mPath, mCastle.getHealth());
		
		mBulletPool = new BulletPool(mBulletTextureRegion,mScene);
		
		mScene.attachChild(mTowerMap.getMap().getTMXLayers().get(0));

		mScene.setTouchAreaBindingEnabled(true);
		
		//configureHUD();
		
		/*mGlideHandler = new IUpdateHandler()
		{
			@Override
			public void onUpdate(float pSecondsElapsed)
			{
				float newScrollX = Game.Engine.getCamera().getCenterX() - mTouchOffsetX;
                float newScrollY = Game.Engine.getCamera().getCenterY() - mTouchOffsetY;
               
                Game.Engine.getCamera().setCenter(newScrollX, newScrollY);
                
                mTouchOffsetX *= 0.85f;
                mTouchOffsetY *= 0.85f;
                
                if(mTouchOffsetX == 0 && mTouchOffsetY == 0)
                {
                	mScene.unregisterUpdateHandler(mGlideHandler);
                }
			}

			@Override
			public void reset() {
				// TODO Auto-generated method stub
			}
		};*/
	}
	
	/*public void assault()
	{
		oldScene = Game.Engine.getScene();
		Game.Engine.setScene(mScene);
		
		mScene.registerUpdateHandler(new IUpdateHandler() 
		{
			@Override
			public void onUpdate(float pSecondsElapsed)
			{
				if(mUnitPool.getCastleHealth() == 0)
				{
					mPlayer.addCastle(mCastle);
					mCastle.setControlled(true, mPlayer);
					Game.Engine.setScene(oldScene);
				}
				else if(mUnitPool.getCount() == 25)
				{
					Game.Engine.setScene(oldScene);
				}
			}

			@Override
			public void reset() {
				// TODO Auto-generated method stub
			}
		});
		
		mScene.registerUpdateHandler(new TimerHandler(1.0f, true, new ITimerCallback() 
		{
			@Override
			public void onTimePassed(TimerHandler pTimerHandler) 
			{
				if(mUnitSpawned != 0)
				{
					mUnitPool.obtainPoolItem();
					mUnitSpawned--;
				}
				else
				{
					mScene.unregisterUpdateHandler(pTimerHandler);
				}
			}
		}));
	}*/
	
	private void configureHUD() {
		Sprite towerButton = new Sprite(0, 0, mTowerTextureRegion)
		{
			@Override
			public boolean onAreaTouched(final TouchEvent pTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
			{				
				if(pTouchEvent.getAction() == MotionEvent.ACTION_DOWN)
				{
					this.setColor(0.8f,0.8f,0.8f,0.3f);
				}
				if(pTouchEvent.getAction() == MotionEvent.ACTION_UP)
				{
					this.setColor(1.0f,1.0f,1.0f,0.6f);
					CreateTower();
				}
				return true;
			}
		};
		
		towerButton.setScale(0.6f);
		towerButton.setPosition(Game.Metrics.widthPixels - towerButton.getWidth(), Game.Metrics.heightPixels - towerButton.getHeight());
		towerButton.setAlpha(0.6f);
		
		final HUD hud = new HUD();
		hud.attachChild(towerButton);
		hud.registerTouchArea(towerButton);
		//Game.Engine.getCamera().setHUD(hud);
	}
	
	private void CreateTower() 
	{
		Toast.makeText(Game.GameContext, "Press screen to place a tower", Toast.LENGTH_LONG).show();
		mTowers.add(new Tower(0,0, mTowerTextureRegion, mTowerRangeTextureRegion, mUnitPool, mBulletPool));
		//mTowers.getLast().attachChild(TowerRegion);
		
		mTowers.getLast().create(mTowerMap.getMap(), mScene, mUsedTiles);

		mPlaceTower = true;
	}

	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pTouchEvent)
	{		
		/*if(mPlaceTower)
		{
			if(mTowers.getLast().place(pTouchEvent, (BoundCamera)Game.Engine.getCamera(), mUsedTiles))
			{
				mTowers.removeLast();
			}
			
			if(pTouchEvent.getAction() == MotionEvent.ACTION_UP)
			{
				mPlaceTower = false;
			}
		}
		else
		{
			if(pTouchEvent.getAction() == MotionEvent.ACTION_DOWN)
	        {
					// Stop any gliding currently in progress
					mScene.unregisterUpdateHandler(mGlideHandler);
					
					// Get the current position of the touch event
	                mTouchX = pTouchEvent.getMotionEvent().getX();
	                mTouchY = pTouchEvent.getMotionEvent().getY();
	        }
			// Move on the screen
	        else if(pTouchEvent.getAction() == MotionEvent.ACTION_MOVE)
	        {
	        		// get the new position of the touch event
	                float newX = pTouchEvent.getMotionEvent().getX();
	                float newY = pTouchEvent.getMotionEvent().getY();
	               
	                // Determine the distance traveled from the previous touch
	                mTouchOffsetX = (newX - mTouchX);
	                mTouchOffsetY = (newY - mTouchY);
	               
	                // Determine the offset for the camera to shift
	                float newScrollX = Game.Engine.getCamera().getCenterX() - mTouchOffsetX;
	                float newScrollY = Game.Engine.getCamera().getCenterY() - mTouchOffsetY;
	               
	                // Set the new camera position
	                Game.Engine.getCamera().setCenter(newScrollX, newScrollY);
	               
	                // Update the variables
	                mTouchX = newX;
	                mTouchY = newY;
	        }
			// On releasing touch event
	        else if(pTouchEvent.getAction() == MotionEvent.ACTION_UP)
	        {
	        	// Start gliding
	        	mScene.registerUpdateHandler(mGlideHandler);
	        }
		}*/
        return true;
	}

}
